#pragma once
#include "Common.h"

template <class T>
class ObjectPool
{
private:
	char* _memory = nullptr;
	size_t _remainsize = 0;
	void* _FreeList = nullptr;

public:
	T* New()
	{
		T* obj = nullptr;
		if (_FreeList)
		{
			void* next = *((void**)_FreeList);
			obj = (T*)_FreeList;
			_FreeList = next;
		}
		else
		{
			if (sizeof(T) > _remainsize)
			{
				_remainsize = 128 * 1024;
				_memory = (char*)SystemAlloc(_remainsize >>13); 
				if (_memory == nullptr)
				{
					throw std::bad_alloc();
				}
			}

			obj = (T*)_memory;
			size_t objsize = sizeof(T) > sizeof(void*) ? sizeof(T) : sizeof(void*);
			_memory += objsize;
			_remainsize -= objsize;
		}
		new(obj)T;
		return obj;
	}

	void Delect(T* obj)
	{
		obj->~T();
		*(void**)obj = _FreeList;
		_FreeList = obj;
	}
};

//struct treenode
//{
//	int _val;
//	treenode* _leftndoe;
//	treenode* _rightnode;
//
//	treenode() :_val(0), _leftndoe(nullptr), _rightnode(nullptr) {}
//};
//
//void test()
//{
//	const size_t round = 3;
//	const size_t N = 100000;
//
//	std::vector<treenode*> v1;
//	v1.reserve(N);
//
//	size_t begin1 = clock();
//	for (size_t i = 0; i < round; ++i)
//	{
//		for (int j = 0; j < N; ++j)
//		{
//			v1.push_back(new treenode);
//		}
//		for (int j = 0; j < N; j++)
//		{
//			delete v1[j];
//		}
//		v1.clear();
//	}
//	size_t end1 = clock();
//
//	std::vector<treenode*> v2;
//	v2.reserve(N);
//	ObjectPool<treenode> tnpool;
//	size_t begin2 = clock();
//
//	for (int i = 0; i < round; ++i)
//	{
//		for (int j = 0; j < N; ++j)
//		{
//			v2.push_back(tnpool.New());
//		}
//		for (int j = 0; j < N; j++)
//		{
//			tnpool.Delect(v2[j]);
//		}
//		v2.clear();
//	}
//	size_t end2 = clock();
//
//	cout << end1 - begin1 << endl;
//	cout << end2 - begin2 << endl;
//}
